The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.
Changes 018
META.yml 55
Makefile.PL 2626
README 11
lib/CPAN/Reporter/API.pod 11
lib/CPAN/Reporter/Config.pm 710
lib/CPAN/Reporter/Config.pod 32
lib/CPAN/Reporter/FAQ.pod 11
lib/CPAN/Reporter/History.pm 11
lib/CPAN/Reporter/History.pod 11
lib/CPAN/Reporter/PrereqCheck.pm 11
lib/CPAN/Reporter/PrereqCheck.pod 11
lib/CPAN/Reporter.pm 2717
lib/CPAN/Reporter.pod 11
t/14_command_timeout.t 3419
t/57_hang_interrupt.t 124
t/Helper.pm 11
17 files changed (This is a version diff) 123110
@@ -1,5 +1,23 @@
 Revision history for Perl module CPAN::Reporter
 
+1.1802 Wed Sep 29 23:19:15 EDT 2010
+
+  Changed:
+
+  - Given the migration to CT2.0, the maximum report length before
+    truncation has been increased from 50 to 1,000 kB.
+
+  - Removed dependency on Proc::ProcessTable for using a command timeout
+    on non-Win32 platforms.
+
+1.1801 Fri Sep 10 16:34:29 EDT 2010
+
+  Changed:
+
+  - Default config directory now uses File::HomeDir->my_home on
+    windows instead of ->my_documents.  If that directory doesn't exist,
+    it will fall back to ->my_documents.
+
 1.1800 Mon Jul 26 16:02:06 EDT 2010
 
   Changed:
@@ -17,16 +17,16 @@ no_index:
 provides:
   CPAN::Reporter:
     file: lib/CPAN/Reporter.pm
-    version: 1.1800
+    version: 1.1802
   CPAN::Reporter::Config:
     file: lib/CPAN/Reporter/Config.pm
-    version: 1.1800
+    version: 1.1802
   CPAN::Reporter::History:
     file: lib/CPAN/Reporter/History.pm
-    version: 1.1800
+    version: 1.1802
   CPAN::Reporter::PrereqCheck:
     file: lib/CPAN/Reporter/PrereqCheck.pm
-    version: 1.1800
+    version: 1.1802
 requires:
   CPAN: 1.9301
   Config::Tiny: 2.08
@@ -48,4 +48,4 @@ requires:
   Test::Reporter: 1.54
 resources:
   license: http://www.apache.org/licenses/LICENSE-2.0.txt
-version: 1.1800
+version: 1.1802
@@ -2,30 +2,30 @@
 use ExtUtils::MakeMaker;
 WriteMakefile
 (
-          'NAME' => 'CPAN::Reporter',
-          'VERSION_FROM' => 'lib/CPAN/Reporter.pm',
-          'PREREQ_PM' => {
-                           'CPAN' => '1.9301',
-                           'Config::Tiny' => '2.08',
-                           'Devel::Autoflush' => '0.04',
-                           'ExtUtils::MakeMaker' => '6.36',
-                           'File::Basename' => 0,
-                           'File::Copy::Recursive' => '0.35',
-                           'File::Find' => 0,
-                           'File::HomeDir' => '0.58',
-                           'File::Path' => 0,
-                           'File::Spec' => '3.19',
-                           'File::Temp' => '0.16',
-                           'File::pushd' => '0.32',
-                           'IO::CaptureOutput' => '1.03',
-                           'Parse::CPAN::Meta' => 0,
-                           'Probe::Perl' => 0,
-                           'Tee' => '0.13',
-                           'Test::More' => '0.62',
-                           'Test::Reporter' => '1.54'
-                         },
-          'INSTALLDIRS' => 'site',
-          'EXE_FILES' => [],
-          'PL_FILES' => {}
-        )
+  'NAME' => 'CPAN::Reporter',
+  'VERSION_FROM' => 'lib/CPAN/Reporter.pm',
+  'PREREQ_PM' => {
+                   'CPAN' => '1.9301',
+                   'Config::Tiny' => '2.08',
+                   'Devel::Autoflush' => '0.04',
+                   'ExtUtils::MakeMaker' => '6.36',
+                   'File::Basename' => 0,
+                   'File::Copy::Recursive' => '0.35',
+                   'File::Find' => 0,
+                   'File::HomeDir' => '0.58',
+                   'File::Path' => 0,
+                   'File::Spec' => '3.19',
+                   'File::Temp' => '0.16',
+                   'File::pushd' => '0.32',
+                   'IO::CaptureOutput' => '1.03',
+                   'Parse::CPAN::Meta' => 0,
+                   'Probe::Perl' => 0,
+                   'Tee' => '0.13',
+                   'Test::More' => '0.62',
+                   'Test::Reporter' => '1.54'
+                 },
+  'INSTALLDIRS' => 'site',
+  'EXE_FILES' => [],
+  'PL_FILES' => {}
+)
 ;
@@ -2,7 +2,7 @@ NAME
     CPAN::Reporter - Adds CPAN Testers reporting to CPAN.pm
 
 VERSION
-    This documentation describes version 1.1800.
+    This documentation describes version 1.1802.
 
 SYNOPSIS
     From the CPAN shell:
@@ -8,7 +8,7 @@ CPAN::Reporter::API - Programmer's interface to CPAN::Reporter
 
 =head1 VERSION
 
-This documentation refers to version 1.1800
+This documentation refers to version 1.1802
 
 =head1 FUNCTIONS
 
@@ -1,7 +1,7 @@
 package CPAN::Reporter::Config;
 use strict; 
 use vars qw/$VERSION/;
-$VERSION = '1.1800';
+$VERSION = '1.1802';
 $VERSION = eval $VERSION; ## no critic
 
 use Config::Tiny ();
@@ -308,11 +308,15 @@ sub _get_config_dir {
     ) {
         return $ENV{PERL_CPAN_REPORTER_DIR};
     }
-    else {
-        return ( $^O eq 'MSWin32' )
-            ? File::Spec->catdir(File::HomeDir->my_documents, ".cpanreporter")
-            : File::Spec->catdir(File::HomeDir->my_home, ".cpanreporter") ;
+
+    my $conf_dir = File::Spec->catdir(File::HomeDir->my_home, ".cpanreporter");
+
+    if ($^O eq 'MSWin32') {
+      my $alt_dir = File::Spec->catdir(File::HomeDir->my_documents, ".cpanreporter");
+      $conf_dir = $alt_dir if -d $alt_dir && ! -d $conf_dir;
     }
+
+    return $conf_dir;
 }
 
 #--------------------------------------------------------------------------#
@@ -532,8 +536,7 @@ From the CPAN shell:
 = DESCRIPTION
 
 Default options for CPAN::Reporter are read from a configuration file 
-{.cpanreporter/config.ini} in the user's home directory (Unix and OS X)
-or "My Documents" directory (Windows).
+{.cpanreporter/config.ini} in the user's home directory.
 
 The configuration file is in "ini" format, with the option name and value
 separated by an "=" sign
@@ -8,7 +8,7 @@ CPAN::Reporter::Config - Config file options for CPAN::Reporter
 
 =head1 VERSION
 
-This documentation refers to version 1.1800
+This documentation refers to version 1.1802
 
 =head1 SYNOPSIS
 
@@ -19,8 +19,7 @@ From the CPAN shell:
 =head1 DESCRIPTION
 
 Default options for CPAN::Reporter are read from a configuration file 
-C<<< .cpanreporter/config.ini >>> in the user's home directory (Unix and OS X)
-or "My Documents" directory (Windows).
+C<<< .cpanreporter/config.ini >>> in the user's home directory.
 
 The configuration file is in "ini" format, with the option name and value
 separated by an "=" sign
@@ -8,7 +8,7 @@ CPAN::Reporter::FAQ - Answers and tips for using CPAN::Reporter
 
 =head1 VERSION
 
-This documentation refers to version 1.1800
+This documentation refers to version 1.1802
 
 =head1 REPORT GRADES
 
@@ -1,7 +1,7 @@
 package CPAN::Reporter::History;
 use strict; 
 use vars qw/$VERSION @ISA @EXPORT_OK/;
-$VERSION = '1.1800';
+$VERSION = '1.1802';
 $VERSION = eval $VERSION; ## no critic
 
 use Config;
@@ -8,7 +8,7 @@ CPAN::Reporter::History - Read or write a CPAN::Reporter history log
 
 =head1 VERSION
 
-This documentation refers to version 1.1800
+This documentation refers to version 1.1802
 
 =head1 SYNOPSIS
 
@@ -1,7 +1,7 @@
 package CPAN::Reporter::PrereqCheck;
 use strict;
 use vars qw/$VERSION/;
-$VERSION = '1.1800';
+$VERSION = '1.1802';
 $VERSION = eval $VERSION; ## no critic
 
 use ExtUtils::MakeMaker;
@@ -8,7 +8,7 @@ CPAN::Reporter::PrereqCheck - Modulino for prerequisite tests
 
 =head1 VERSION
 
-This documentation describes version 1.1800.
+This documentation describes version 1.1802.
 
 =head1 SYNOPSIS
 
@@ -1,7 +1,7 @@
 package CPAN::Reporter;
 use strict;
 use vars qw/$VERSION/;
-$VERSION = '1.1800';
+$VERSION = '1.1802';
 $VERSION = eval $VERSION; ## no critic
 
 use Config;
@@ -22,7 +22,7 @@ use CPAN::Reporter::Config ();
 use CPAN::Reporter::History ();
 use CPAN::Reporter::PrereqCheck ();
 
-use constant MAX_OUTPUT_LENGTH => 50_000;
+use constant MAX_OUTPUT_LENGTH => 1_000_000;
 
 #--------------------------------------------------------------------------#
 # create temp lib dir for Devel::Autoflush
@@ -173,7 +173,7 @@ HERE
     $output_fh->close;
 
     # cleanup
-    unlink $wrapper_name, $temp_out;
+    unlink $wrapper_name, $temp_out unless $ENV{PERL_CR_NO_CLEANUP};
 
     if ( ! @cmd_output ) {
         $CPAN::Frontend->mywarn(
@@ -1188,50 +1188,40 @@ sub _temp_filename {
 
 #--------------------------------------------------------------------------#
 # _timeout_wrapper
+# Timeout technique adapted from App::cpanminus (thank you Miyagawa!)
 #--------------------------------------------------------------------------#
 
 sub _timeout_wrapper {
     my ($cmd, $timeout) = @_;
 
-    # Check Proc::ProcessTable also in case an unauthorized Proc::Killfam is
-    # present, as from Tk-ExecuteCommand
-    {
-      local $SIG{__WARN__} = sub {};  # protect against v-string warning
-      eval "require Proc::ProcessTable; require Proc::Killfam"; ## no critic
-    }
-    if ($@) {
-        $CPAN::Frontend->mywarn( << 'HERE' );
-CPAN::Reporter: you need Proc::ProcessTable and Proc::Killfam for
-inactivity_timeout support.  Continuing without timeout...
-HERE
-        return;
-    }
-
     # protect shell quotes
     $cmd = quotemeta($cmd);
 
     my $wrapper = sprintf << 'HERE', $timeout, $cmd, $cmd;
 use strict;
-use Proc::Killfam 'killfam';
 my ($pid, $exitcode);
 eval {
-    local $SIG{CHLD};
-    local $SIG{ALRM} = sub {die 'Timeout'};
+    setpgrp(0,0); # new process group
     $pid = fork;
-    die "Cannot fork: $!\n" unless defined $pid;
-    if ($pid) { #parent
+    if ($pid) {
+        local $SIG{CHLD};
+        local $SIG{ALRM} = sub {die 'Timeout'};
         alarm %s;
         my $wstat = waitpid $pid, 0;
+        alarm 0;
         $exitcode = $wstat == -1 ? -1 : $?;
-    } else {    #child
+    } elsif ( $pid == 0 ) {
         exec "%s";
     }
+    else {
+      die "Cannot fork: $!\n" unless defined $pid;
+    }
 };
-alarm 0;
 if ($pid && $@ =~ /Timeout/){
-    killfam 9, $pid;
-    my $wstat = waitpid $pid, 0;
-    $exitcode = $wstat == -1 ? -1 : $?;
+    local $SIG{TERM} = 'IGNORE'; # ignore TERM
+    kill 'TERM' => 0; # and send to our whole process group
+    waitpid $pid, 0;
+    $exitcode = 15; # force result to look like SIGTERM
 }
 elsif ($@) {
     die $@;
@@ -8,7 +8,7 @@ CPAN::Reporter - Adds CPAN Testers reporting to CPAN.pm
 
 =head1 VERSION
 
-This documentation describes version 1.1800.
+This documentation describes version 1.1802.
 
 =head1 SYNOPSIS
 
@@ -13,20 +13,12 @@ use IO::CaptureOutput qw/capture/;
 use Probe::Perl ();
 
 #--------------------------------------------------------------------------#
-# Skip on Win32 if except for author or without Proc::Killfam/Win32::Job
+# Skip on Win32 except for release testing
 #--------------------------------------------------------------------------#
 
-if ( $^O ne 'MSWin32' ) {
-  {
-    local $SIG{__WARN__} = sub {}; # suppress v-string warnings
-    eval "require Proc::ProcessTable; require Proc::Killfam";
-  }
-  plan skip_all => "requires Proc::ProcessTable and Proc::Killfam"
-    if $@;
-}
 if ( $^O eq "MSWin32" ) {
-    plan skip_all => "\$ENV{PERL_AUTHOR_TESTING} required for Win32 timeout testing", 
-        unless $ENV{PERL_AUTHOR_TESTING};
+    plan skip_all => "\$ENV{RELEASE_TESTING} required for Win32 timeout testing", 
+        unless $ENV{RELEASE_TESTING};
     eval "use Win32::Job ()";
     plan skip_all => "Can't interrupt hung processes without Win32::Job"
         if $@;
@@ -46,39 +38,35 @@ my $quote = $^O eq 'MSWin32' || $^O eq 'MSDOS' ? q{"} : q{'};
 
 my @cases = (
     {
-        label => "regular < command < program",
+        label => "regular < global < delay",
         program => '$now=time(); 1 while( time() - $now < 60); print qq{foo\n}; exit 0',
-        args => '',
         output => [],
         timeout => 5,
         command_timeout => 30,
         delay => 60,
-        exit_code => 9,
+        exit_code => 15,
     },
     {
-        label => "regular < program < command",
+        label => "regular < delay < global",
         program => '$now=time(); 1 while( time() - $now < 30); print qq{foo\n}; exit 0',
-        args => '',
         output => [],
         timeout => 5,
         delay => 30,
         command_timeout => 60,
-        exit_code => 9,
+        exit_code => 15,
     },
     {
-        label => "command < regular < program",
+        label => "global < regular < delay",
         program => '$now=time(); 1 while( time() - $now < 60); print qq{foo\n}; exit 0',
-        args => '',
         output => [],
         command_timeout => 2,
         timeout => 5,
         delay => 60,
-        exit_code => 9,
+        exit_code => 15,
     },
     {
-        label => "command < program < regular",
+        label => "global < delay < regular",
         program => '$now=time(); 1 while( time() - $now < 5); print qq{foo\n}; exit 0',
-        args => '',
         output => ["foo\n"],
         command_timeout => 2,
         delay => 5,
@@ -86,9 +74,8 @@ my @cases = (
         exit_code => 0,
     },
     {
-        label => "program < regular < command",
+        label => "delay < regular < global",
         program => '$now=time(); 1 while( time() - $now < 2); print qq{foo\n}; exit 0',
-        args => '',
         output => ["foo\n"],
         delay => 2,
         timeout => 30,
@@ -96,9 +83,8 @@ my @cases = (
         exit_code => 0,
     },
     {
-        label => "program < command < regular",
+        label => "delay < global < regular",
         program => '$now=time(); 1 while( time() - $now < 2); print qq{foo\n}; exit 0',
-        args => '',
         output => ["foo\n"],
         delay => 2,
         command_timeout => 30,
@@ -106,18 +92,16 @@ my @cases = (
         exit_code => 0,
     },
     {
-        label => "command < program",
+        label => "global < delay",
         program => '$now=time(); 1 while( time() - $now < 30); print qq{foo\n}; exit 0',
-        args => '',
         output => [],
         command_timeout => 5,
         delay => 30,
-        exit_code => 9,
+        exit_code => 15,
     },
     {
-        label => "program < command",
+        label => "delay < global",
         program => '$now=time(); 1 while( time() - $now < 2); print qq{foo\n}; exit 0',
-        args => '',
         output => ["foo\n"],
         delay => 2,
         command_timeout => 30,
@@ -143,7 +127,7 @@ SKIP: {
                      ? ( command_timeout => $c->{command_timeout} ) : ();
     test_fake_config( @extra_config );
 
-    my $fh = File::Temp->new() 
+    my $fh = File::Temp->new( UNLINK => ! $ENV{PERL_CR_NO_CLEANUP} )
         or die "Couldn't create a temporary file: $!\nIs your temp drive full?";
     print {$fh} $c->{program}, "\n";
     $fh->flush;
@@ -151,11 +135,12 @@ SKIP: {
     my ($stdout, $stderr);
     my $start_time = time();
     my $cmd = $c->{relative} ? "perl" : $perl; 
+    $cmd .= " $fh";
     warn "# sleeping for timeout test\n" if $c->{delay};
     eval {
         capture sub {
             ($output, $exit) = CPAN::Reporter::record_command( 
-                "$cmd $fh $c->{args}", $c->{timeout}
+                $cmd, $c->{timeout}
             );
         }, \$stdout, \$stderr;
     };
@@ -220,7 +205,7 @@ SKIP: {
     }
 
     ok( $time_ok, "$c->{label}: $who timeout") or diag $diag;
-    like( $stdout, "/" . quotemeta(join(q{},@$output)) . "/", 
+    like( $stdout, "/" . quotemeta(join(q{},@{ $output || [] })) . "/", 
         "$c->{label}: captured stdout" 
     );
     is_deeply( $output, $c->{output},  "$c->{label}: output as expected" )
@@ -10,20 +10,12 @@ use Probe::Perl;
 use File::Temp;
 
 #--------------------------------------------------------------------------#
-# Skip on Win32 if except for author or without Proc::Killfam/Win32::Job
+# Skip on Win32 except for release testing
 #--------------------------------------------------------------------------#
 
-if ( $^O ne 'MSWin32' ) {
-  {
-    local $SIG{__WARN__} = sub {}; # suppress v-string warnings
-    eval "require Proc::ProcessTable; require Proc::Killfam";
-  }
-  plan skip_all => "requires Proc::ProcessTable and Proc::Killfam"
-    if $@;
-}
 if ( $^O eq "MSWin32" ) {
-    plan skip_all => "\$ENV{PERL_AUTHOR_TESTING} required for Win32 timeout testing", 
-        unless $ENV{PERL_AUTHOR_TESTING};
+    plan skip_all => "\$ENV{RELEASE_TESTING} required for Win32 timeout testing", 
+        unless $ENV{RELEASE_TESTING};
     eval "use Win32::Job ()";
     plan skip_all => "Can't interrupt hung processes without Win32::Job"
         if $@;
@@ -101,7 +93,7 @@ for my $case ( @cases ) {
         pretty_id => $case->{pretty_id},
         %mock_dist_options,
     );
-    test_fake_config( command_timeout => 5 );
+    test_fake_config( command_timeout => 3 );
     test_dispatch( 
         $case, 
         will_send => $case->{will_send},
@@ -58,7 +58,7 @@ my %tool_constants = (
     },
 );
 
-my $max_report_length = 50_000; # 50K
+my $max_report_length = 1_000_000; # 1000K
 
 # used to capture from fixtures
 use vars qw/$sent_report @cc_list/;